package insat.ia.main;

import java.io.ObjectInputStream.GetField;
import java.util.ArrayList;

public class InferenceEngine_Arriere extends InferenceEngine {

    // liste de buts
    ArrayList<String> ListBut;

    public InferenceEngine_Arriere(Dataengine dataengine, String but) {
        this.dataengine = dataengine;
        But = but;
    }

    public boolean chainageArriere(String But, String concl) {

        boolean result = true;
        boolean resultGenerale = false;

        Premisse but = new Premisse();
        but.add(But);
        ArrayList<Fait> bf = this.dataengine.getBFobjects();
        ArrayList<Regle> br = this.dataengine.getBRobjects();

        //Si but appartient BF
        if (match(but, bf)) {
            butAttient = true;
            Fait f = new Fait(-1, concl);
            this.dataengine.BFobjects.add(f);
            System.out.println("  "+but + " appartient a la base de fait");
            return true;
        } else {
            //retourner la liste de regles dechlanchables 
            ArrayList<Regle> tmp = getReglesDeclenchableSet(but);
            System.out.println("  Nombre du regles declenchables : "
                    + tmp.size());
            //si acune regle dechlanchable
            if (tmp.isEmpty()) {
                return false;
            } else {
                //sinon rech s'il est déductible des autres regles

                //pour chaque regle
                for (int i = 0; i < tmp.size(); i++) {
                    result = true;
                    nbReglesAppliquee++;
                    ArrayList<String> newListeBut = appliqueRegle(tmp.get(i));
                    String conc = tmp.get(i).getConclusion();

                    //pour chaque premisse
                    for (int j = 0; j < newListeBut.size(); j++) {
                        System.out.println("Pour le but "+newListeBut.get(j));

                        boolean resultRecursiveCall = chainageArriere(newListeBut.get(j), conc);
                        if (!resultRecursiveCall) {
                            result = false;
                            break;
                        } else {
                            result = result && resultRecursiveCall;
                        }
                    }

                    resultGenerale = result || resultGenerale;
                    if (resultGenerale) {
                        break;
                    }
                }
                // appliqueRegle(regleChoisie);
                this.dataengine.showData();
            }
        }
        return resultGenerale;
    }

    public ArrayList<String> appliqueRegle(Regle r) {

        System.out.println("  Application de la regle " + r);

        // applique la regle
        ArrayList<String> but = r.getPremisse();

        // desactiver la regle
        this.dataengine.getBRobjects().remove(r);

        return but;
    }

    /*
     * resolution de conflit selon l'ordre da'pparition
     */
    public Regle conflictResolution(ArrayList<Regle> reglesDeclenchableSet) {

        return reglesDeclenchableSet.get(0);

    }

    /*
     * retourne l'ensemble de regles declenchables
     */
    public ArrayList<Regle> getReglesDeclenchableSet(Premisse but) {

        ArrayList<Regle> result = new ArrayList<Regle>();

        for (int i = 0; i < dataengine.getBRobjects().size(); i++) {
//            System.out.println("test de la regle "
//                    + dataengine.BRobjects.get(i).getNumero());

            if (but.contains(dataengine.BRobjects.get(i).getConclusion())) {
                result.add(dataengine.BRobjects.get(i));
            }

        }
        return result;

    }

}
